# coding:utf-8
import os
import sys
import json
from typing import Callable, Dict, List, Optional, Any, Union
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtWidgets import (
    QWidget,
    QHBoxLayout,
    QVBoxLayout,
    QFrame,
    QFormLayout,
    QLabel,
    QSlider,
    QLineEdit,
    QComboBox,
    QSpinBox,
    QPushButton,
    QTableWidget,
    QTableWidgetItem,
    QHeaderView,
    QSpacerItem,
    QSizePolicy,
    QCompleter,
    QTextEdit,
    QLayout,
)
from qfluentwidgets import (
    StrongBodyLabel,
    CardWidget,
    MessageBoxBase,
    SearchLineEdit,
    LineEdit,
    Slider,
    SubtitleLabel,
)
from qframelesswindow import AcrylicWindow, FramelessWindow
from qframelesswindow import AcrylicWindow
from qframelesswindow.webengine import FramelessWebEngineView

from common.utils.utils_log import AntLogger
from views.common.style_sheet import StyleSheet

from .base_gallery_view import GalleryInterface
from .common.translator import Translator
from .template.dynamic_form_template import DynamicFormTemplate
from .template.main_card_template import MainCardTemplate
from .template.main_form_template import MainFormTemplate
from .template.main_table_template import MainTableTemplate
from .template.main_key_value_form import MainKeyValueFrom
from .template.main_echat_template import MainEchatTemplate
from .template.top_search_template import TopSearchTemplate, TopTemplateSearchLineEdit
from .template.data_classes import (
    FormItemDto,
    TableDataDto,
    ComponentConfig,
    WidgetTemplateResultDto,
)


class BasePageTemplateView(GalleryInterface):
    """Scroll interface"""

    def __init__(self, objectName, parent=None):
        t = Translator()
        super().__init__(
            title=t.scroll, subtitle="qfluentwidgets.components.widgets", parent=parent
        )
        self.setObjectName(objectName)
        self.loaded = False
        self.searchKey = ""
        self.childTempalte = {}

        # 样式文件基础路径
        self.qss_base_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), "qss", "plugin"
        )

    # 获取样式文件路径
    def get_style_path(self, style_name: str) -> str:
        """
        获取样式文件的完整路径

        Args:
            style_name: 样式文件名，如 "form_style.qss"

        Returns:
            str: 样式文件的完整路径
        """
        return os.path.join(self.qss_base_path, style_name)

    # 应用样式到组件
    def apply_style_to_widget(
        self, widget_result: WidgetTemplateResultDto, style_name: str
    ) -> None:
        """
        应用指定样式到组件

        Args:
            widget_result: 组件模板结果对象
            style_name: 样式文件名，如 "form_style.qss"
        """
        style_path = self.get_style_path(style_name)
        widget_result.style_file = style_path
        widget_result.apply_style()
        AntLogger.info(f"应用样式: {style_path} 到组件")

    def getTopView(self):
        return QWidget

    # 添加外部组件
    def addOutLayout(self, layout: QLayout) -> QLayout:
        self.vBoxLayout.addLayout(layout)
        return layout

    # 添加表单组件
    def addFromTemplate(
        self,
        form_items: List[FormItemDto],
        title: str,
        callback: Callable,
        stretch: int = 0,
        layout: Optional[QLayout] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:
        form = MainFormTemplate(form_items, callback)
        card = MainCardTemplate(title, form, stretch, self.view)

        target_layout = layout if layout is not None else self.vBoxLayout
        target_layout.addWidget(card, stretch, Qt.AlignmentFlag.AlignTop)

        self.childTempalte[title] = form

        # 返回组件模板结果数据传输对象
        result = WidgetTemplateResultDto(
            inner=form, card=card, target_layout=target_layout, style_file=style_file
        )

        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()

        return result

    # 添加报表组件
    def addEchatTemplate(
        self,
        title: str,
        chatName: str,
        dataFun: Callable[[str, Dict[str, str]], str],
        datParamFun: Callable[[], Dict[str, str]],
        stretch: int = 0,
        layout: Optional[QLayout] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:

        chat = MainEchatTemplate(self, chatName, dataFun, datParamFun)
        card = MainCardTemplate(title, chat, stretch, self.view)

        if sys.platform == "win32" and isinstance(card.window(), AcrylicWindow):
            card.window().setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        if isinstance(card.window(), FramelessWindow):
            card.window().updateFrameless()

        target_layout = layout if layout is not None else self.vBoxLayout
        target_layout.addWidget(card, stretch, Qt.AlignmentFlag.AlignTop)

        self.childTempalte[title] = chat

        # 返回组件模板结果数据传输对象
        result = WidgetTemplateResultDto(
            inner=chat, card=card, target_layout=target_layout, style_file=style_file
        )

        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()

        return result

    # 添加表格组件
    def addTableTemplate(
        self,
        title: str,
        dataFun: Callable[[Dict[str, str]], TableDataDto],
        datParamFun: Callable[[], Dict[str, str]],
        stretch: int = 0,
        layout: Optional[QLayout] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:

        table = MainTableTemplate(dataFun, datParamFun)
        card = MainCardTemplate(title, table, stretch, self.view)

        target_layout = layout if layout is not None else self.vBoxLayout
        target_layout.addWidget(card, stretch, Qt.AlignmentFlag.AlignTop)

        self.childTempalte[title] = table

        # 返回组件模板结果数据传输对象
        result = WidgetTemplateResultDto(
            inner=table, card=card, target_layout=target_layout, style_file=style_file
        )

        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()

        return result

    # 添加Key-value报表组件
    def addKeyValueFormTemplate(
        self,
        title: str,
        dataFun: Callable[[str, Dict[str, str]], Dict[str, str]],
        datParamFun: Callable[[], Dict[str, str]],
        stretch: int = 0,
        layout: Optional[QLayout] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:
        form = MainKeyValueFrom(dataFun, datParamFun)
        card = MainCardTemplate(title, form, stretch, self.view)

        target_layout = layout if layout is not None else self.vBoxLayout
        target_layout.addWidget(card, stretch, Qt.AlignmentFlag.AlignTop)

        self.childTempalte[title] = form

        # 返回组件模板结果数据传输对象
        result = WidgetTemplateResultDto(
            inner=form, card=card, target_layout=target_layout, style_file=style_file
        )

        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()

        return result

    def addTopOperation(
        self,
        title: str,
        component_configs: List[ComponentConfig],  # 组件类型与回调函数的映射
        datParamFun: Callable[[], Dict[str, str]],
        stretch: int = 0,
        layout: Optional[QLayout] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:
        top = TopSearchTemplate(component_configs, datParamFun)
        target_layout = layout if layout is not None else self.vBoxLayout
        target_layout.addWidget(top, stretch, Qt.AlignmentFlag.AlignTop)

        # 返回组件模板结果数据传输对象
        result = WidgetTemplateResultDto(
            inner=top,
            card=top,  # 顶部操作组件没有卡片包装，所以card就是组件本身
            target_layout=target_layout,
            style_file=style_file,
        )

        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()

        return result

    def showEvent(self, event):
        super().showEvent(event)
        if not self.loaded:
            self.loaded = True
            self.doInitAndUpdate()
            StyleSheet.GALLERY_INTERFACE.apply(self)

    # 刷新单个 Template 的数据
    def refreshDataForTemplate(self, title: str) -> bool:
        """
        刷新指定标题的 Template 数据

        Args:
            title: 模板标题

        Returns:
            bool: 是否成功刷新
        """
        template = self.childTempalte.get(title)
        if template:
            # 检查是否具有 refreshData 方法
            if hasattr(template, "refreshData") and callable(
                getattr(template, "refreshData")
            ):
                template.refreshData()
                return True
            else:
                AntLogger.info(f"模板 '{title}' 没有实现 refreshData 方法")
                return False
        else:
            AntLogger.info(f"没有找到标题为 '{title}' 的 Template")
            return False

    # 刷新所有 Template 的数据
    def refreshAllData(self) -> Dict[str, bool]:
        """
        刷新所有 Template 的数据

        Returns:
            Dict[str, bool]: 每个模板的刷新结果，True表示成功刷新
        """
        results = {}
        for title, template in self.childTempalte.items():
            # 检查是否具有 refreshData 方法
            if hasattr(template, "refreshData") and callable(
                getattr(template, "refreshData")
            ):
                try:
                    template.refreshData()
                    results[title] = True
                except Exception as e:
                    AntLogger.error(f"刷新模板 '{title}' 时出错: {str(e)}")
                    results[title] = False
            else:
                AntLogger.info(f"模板 '{title}' 没有实现 refreshData 方法")
                results[title] = False
        return results

    # 添加自定义弹窗表单
    def addCustomBox(
        self,
        title: str,
        form_config: List[Dict[str, Any]] = None,
        on_submit: Callable[[Dict[str, Any]], None] = None,
        style_file: str = "",
    ) -> WidgetTemplateResultDto:
        """
        添加自定义弹窗表单
        
        Args:
            title: 表单标题
            form_config: 表单配置列表，每项为字典，描述控件类型、标签、默认值等
            on_submit: 提交回调函数，接收表单数据作为参数
            style_file: 样式文件路径
            
        Returns:
            WidgetTemplateResultDto: 组件模板结果对象
        """
        box = DynamicFormTemplate(
            parent=self,
            form_config=form_config,
            title=title,
            on_submit=on_submit
        )
        
        # 将表单添加到组件列表中
        self.childTempalte[title] = box
        
        # 创建并返回结果对象
        result = WidgetTemplateResultDto(
            inner=box,
            card=None,  # 弹窗不需要卡片容器
            target_layout=None,  # 弹窗不需要布局
            style_file=style_file
        )
        
        # 如果提供了样式文件，立即应用样式
        if style_file:
            result.apply_style()
            
        # 显示表单
        box.exec()
        
        return result
